package com.ffggffgfv.backend.service.impl;

import com.ffggffgfv.backend.dto.*;
import com.ffggffgfv.backend.entity.Admin;
import com.ffggffgfv.backend.entity.AdminRole;
import com.ffggffgfv.backend.mapper.AdminMapper;
import com.ffggffgfv.backend.mapper.AdminRoleMapper;
import com.ffggffgfv.backend.mapper.PermissionMapper;
import com.ffggffgfv.backend.service.AdminService;
import com.ffggffgfv.backend.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 管理员服务实现类
 */
@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JWTUtil jwtUtil;

    /**
     * 管理员登录
     *
     * @param loginDTO 登录信息
     * @return 登录结果
     */
    @Override
    public Map<String, Object> login(AdminLoginDTO loginDTO) {
        // 根据用户名查询管理员
        Admin admin = adminMapper.selectByUsername(loginDTO.getUsername());

        // 验证管理员是否存在且密码是否正确
        if (admin == null || !passwordEncoder.matches(loginDTO.getPassword(), admin.getPassword())) {
            return null;
        }

        // 验证账号状态是否正常
        if (admin.getStatus() != null && admin.getStatus() != 1) {
            return null;
        }

        // 查询管理员角色
        List<String> roles = adminRoleMapper.selectRoleCodesByAdminId(admin.getId());

        // 生成JWT令牌
        String token = jwtUtil.generateToken(admin.getUsername(), admin.getId(), roles);

        // 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("adminId", admin.getId());
        result.put("username", admin.getUsername());
        result.put("avatarUrl", admin.getAvatarUrl());
        result.put("roles", roles);

        return result;
    }

    /**
     * 通过ID获取管理员信息
     *
     * @param id 管理员ID
     * @return 管理员详细信息
     */
    @Override
    public AdminInfoDTO getAdminInfo(Long id) {
        // 查询管理员
        Admin admin = adminMapper.selectById(id);
        if (admin == null) {
            return null;
        }

        // 查询角色和权限
        List<String> roles = adminRoleMapper.selectRoleCodesByAdminId(id);
        List<String> permissions = permissionMapper.selectCodesByAdminId(id);

        // 构建管理员信息DTO
        AdminInfoDTO adminInfoDTO = new AdminInfoDTO();
        adminInfoDTO.setId(admin.getId());
        adminInfoDTO.setUsername(admin.getUsername());
        adminInfoDTO.setAvatarUrl(admin.getAvatarUrl());
        adminInfoDTO.setStatus(admin.getStatus());
        adminInfoDTO.setCreateTime(admin.getCreateTime());
        adminInfoDTO.setRoles(roles);
        adminInfoDTO.setPermissions(permissions);

        return adminInfoDTO;
    }

    /**
     * 通过ID获取管理员实体
     *
     * @param id 管理员ID
     * @return 管理员实体
     */
    @Override
    public Admin findById(Long id) {
        return adminMapper.selectById(id);
    }

    /**
     * 通过用户名获取管理员实体
     *
     * @param username 用户名
     * @return 管理员实体
     */
    @Override
    public Admin findByUsername(String username) {
        return adminMapper.selectByUsername(username);
    }

    /**
     * 分页查询管理员列表
     *
     * @param username 用户名（可选）
     * @param status   状态（可选）
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @return 分页结果
     */
    @Override
    public PageResult<Admin> findByPage(String username, Integer status, int pageNum, int pageSize) {
        // 计算偏移量
        int offset = (pageNum - 1) * pageSize;

        // 查询总数
        long total = adminMapper.countAll(username, status);

        // 查询当前页数据
        List<Admin> admins = adminMapper.selectByPage(username, status, offset, pageSize);

        // 返回分页结果
        return new PageResult<>(admins, total, pageNum, pageSize);
    }

    /**
     * 创建管理员
     *
     * @param admin 管理员对象
     * @return 创建的管理员
     */
    @Override
    public Admin createAdmin(Admin admin) {
        // 设置默认头像
        if (admin.getAvatarUrl() == null) {
            admin.setAvatarUrl("/images/avatar/default0.jpg");
        }

        // 设置默认状态
        if (admin.getStatus() == null) {
            admin.setStatus(1);
        }

        // 密码加密
        admin.setPassword(passwordEncoder.encode(admin.getPassword()));

        // 设置创建和更新时间
        Date now = new Date();
        admin.setCreateTime(now);
        admin.setUpdateTime(now);

        // 插入数据
        adminMapper.insert(admin);

        return admin;
    }

    /**
     * 更新管理员信息
     *
     * @param id        管理员ID
     * @param updateDTO 更新信息
     * @return 更新后的管理员
     */
    @Override
    public Admin updateAdmin(Long id, AdminUpdateDTO updateDTO) {
        // 查询原管理员
        Admin existingAdmin = adminMapper.selectById(id);
        if (existingAdmin == null) {
            return null;
        }

        // 如果修改密码
        if (updateDTO.getOldPassword() != null && updateDTO.getNewPassword() != null) {
            // 验证旧密码
            if (!passwordEncoder.matches(updateDTO.getOldPassword(), existingAdmin.getPassword())) {
                return null;
            }

            // 更新密码
            String encodedPassword = passwordEncoder.encode(updateDTO.getNewPassword());
            adminMapper.updatePassword(id, encodedPassword, new Date());
        }

        // 如果更新头像
        if (updateDTO.getAvatarUrl() != null) {
            Admin admin = new Admin();
            admin.setId(id);
            admin.setAvatarUrl(updateDTO.getAvatarUrl());
            admin.setUpdateTime(new Date());
            adminMapper.update(admin);
        }

        return adminMapper.selectById(id);
    }

    /**
     * 修改管理员状态
     *
     * @param id     管理员ID
     * @param status 状态（0-停用 1-启用）
     * @return 是否成功
     */
    @Override
    public boolean updateStatus(Long id, Integer status) {
        // 查询原管理员
        Admin existingAdmin = adminMapper.selectById(id);
        if (existingAdmin == null) {
            return false;
        }

        // 更新状态
        return adminMapper.updateStatus(id, status, new Date()) > 0;
    }

    /**
     * 分配管理员角色
     *
     * @param adminId     管理员ID
     * @param userRoleDTO 角色ID列表
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignRoles(Long adminId, UserRoleDTO userRoleDTO) {
        // 先删除当前管理员的所有角色关联
        adminRoleMapper.deleteByAdminId(adminId);

        // 如果角色ID列表为空，则直接返回成功
        if (userRoleDTO.getRoleIds() == null || userRoleDTO.getRoleIds().isEmpty()) {
            return true;
        }

        // 构建管理员角色关联对象列表
        List<AdminRole> adminRoles = new ArrayList<>();
        Date now = new Date();

        for (Long roleId : userRoleDTO.getRoleIds()) {
            AdminRole ar = new AdminRole();
            ar.setAdminId(adminId);
            ar.setRoleId(roleId);
            ar.setCreateTime(now);
            adminRoles.add(ar);
        }

        // 批量插入管理员角色关联
        return adminRoleMapper.batchInsert(adminRoles) > 0;
    }

    /**
     * 判断用户名是否已存在
     *
     * @param username 用户名
     * @return 是否存在
     */
    @Override
    public boolean isUsernameExists(String username) {
        return adminMapper.selectByUsername(username) != null;
    }

    /**
     * 管理员注册（仅用于测试）
     *
     * @param registerDTO 注册信息
     * @return 注册成功的管理员信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Admin register(AdminRegisterDTO registerDTO) {
        // 1. 创建管理员实体
        Admin admin = new Admin();
        admin.setUsername(registerDTO.getUsername());
        admin.setPassword(passwordEncoder.encode(registerDTO.getPassword()));

        // 2. 设置头像，如果没有提供则使用默认头像
        if (registerDTO.getAvatarUrl() == null || registerDTO.getAvatarUrl().trim().isEmpty()) {
            admin.setAvatarUrl("/images/avatar/default0.jpg");
        } else {
            admin.setAvatarUrl(registerDTO.getAvatarUrl());
        }

        // 3. 设置状态为启用
        admin.setStatus(1);

        // 4. 设置创建和更新时间
        Date now = new Date();
        admin.setCreateTime(now);
        admin.setUpdateTime(now);

        // 5. 插入数据
        adminMapper.insert(admin);

        // 6. 分配初始角色（为了测试方便，这里可以直接分配管理员角色）
        AdminRole adminRole = new AdminRole();
        adminRole.setAdminId(admin.getId());
        adminRole.setRoleId(2L); // 2是系统管理员角色
        adminRole.setCreateTime(now);

        // 7. 插入角色关联
        List<AdminRole> adminRoles = new ArrayList<>();
        adminRoles.add(adminRole);
        adminRoleMapper.batchInsert(adminRoles);

        return admin;
    }
}
